using AutoMapper;
using MediatR;
using Microsoft.EntityFrameworkCore;
using S.M.SmartMedical.API.Read.Application.Query;
using S.M.SmartMedical.Domain.Entities;
using S.M.SmartMedical.Domain.Enums;
using S.M.SmartMedical.ErrorCode;
using S.M.SmartMedical.Infrastructure.BaseRepository;

namespace S.M.SmartMedical.API.Read.Application.Handler;

/// <summary>
/// 获取开单申请列表处理器
/// </summary>
public class GetOrderApplicationsHandler : IRequestHandler<GetOrderApplicationsQuery, APIResult<PagedResult<OrderApplicationDto>>>
{
    private readonly IRepository<OrderApplication> _orderApplicationRepository;
    private readonly IMapper _mapper;
    private readonly ILogger<GetOrderApplicationsHandler> _logger;

    public GetOrderApplicationsHandler(
        IRepository<OrderApplication> orderApplicationRepository,
        IMapper mapper,
        ILogger<GetOrderApplicationsHandler> logger)
    {
        _orderApplicationRepository = orderApplicationRepository;
        _mapper = mapper;
        _logger = logger;
    }

    public async Task<APIResult<PagedResult<OrderApplicationDto>>> Handle(GetOrderApplicationsQuery request, CancellationToken cancellationToken)
    {
        try
        {
            _logger.LogInformation("开始查询开单申请列表，用户ID：{UserId}，院区ID：{HospitalAreaId}，状态：{Status}，页码：{PageIndex}，页大小：{PageSize}", 
                request.UserId, request.HospitalAreaId, request.Status, request.PageIndex, request.PageSize);

            // 构建查询条件
            var query = _orderApplicationRepository.GetQueryable()
                .Include(x => x.User)
                .Include(x => x.HospitalArea)
                .Where(x => !x.IsDeleted);

            // 按用户ID过滤
            if (request.UserId.HasValue)
            {
                query = query.Where(x => x.UserId == request.UserId.Value);
            }

            // 按院区ID过滤
            if (request.HospitalAreaId.HasValue)
            {
                query = query.Where(x => x.HospitalAreaId == request.HospitalAreaId.Value);
            }

            // 按状态过滤
            if (request.Status.HasValue)
            {
                query = query.Where(x => x.Status == request.Status.Value);
            }

            // 按申请编号过滤（模糊搜索）
            if (!string.IsNullOrWhiteSpace(request.ApplicationNumber))
            {
                query = query.Where(x => x.ApplicationNumber.Contains(request.ApplicationNumber));
            }

            // 按日期范围过滤
            if (request.StartDate.HasValue)
            {
                query = query.Where(x => x.CreateTime >= request.StartDate.Value);
            }

            if (request.EndDate.HasValue)
            {
                var endDate = request.EndDate.Value.Date.AddDays(1); // 包含结束日期的整天
                query = query.Where(x => x.CreateTime < endDate);
            }

            // 排序
            query = ApplySorting(query, request.SortField, request.SortAscending);

            // 获取总数
            var totalCount = await query.CountAsync(cancellationToken);

            // 分页
            var items = await query
                .Skip((request.PageIndex - 1) * request.PageSize)
                .Take(request.PageSize)
                .ToListAsync(cancellationToken);

            // 映射到DTO
            var dtoItems = items.Select(x => new OrderApplicationDto
            {
                Id = x.Id,
                ApplicationNumber = x.ApplicationNumber,
                UserId = x.UserId,
                UserName = x.User?.RealName ?? x.User?.UserName ?? "未知用户",
                HospitalAreaId = x.HospitalAreaId,
                HospitalAreaName = x.HospitalArea?.Name ?? "未知院区",
                Status = x.Status,
                StatusDescription = GetStatusDescription(x.Status),
                ProjectCount = x.ProjectCount,
                TotalAmount = x.TotalAmount,
                Remarks = x.Remarks,
                AppointmentDate = x.AppointmentDate,
                AppointmentTimeSlot = x.AppointmentTimeSlot,
                ContactPhone = x.ContactPhone,
                CreateTime = x.CreateTime,
                UpdateTime = x.UpdateTime
            }).ToList();

            var pagedResult = new PagedResult<OrderApplicationDto>
            {
                Items = dtoItems,
                TotalCount = totalCount,
                PageIndex = request.PageIndex,
                PageSize = request.PageSize,
                TotalPages = (int)Math.Ceiling((double)totalCount / request.PageSize)
            };

            _logger.LogInformation("查询开单申请列表成功，总数：{TotalCount}，当前页：{PageIndex}，页大小：{PageSize}", 
                totalCount, request.PageIndex, request.PageSize);

            return new APIResult<PagedResult<OrderApplicationDto>>
            {
                Code = APIEnum.OK,
                Message = "查询成功",
                Data = pagedResult
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "查询开单申请列表时发生异常，用户ID：{UserId}", request.UserId);
            
            return new APIResult<PagedResult<OrderApplicationDto>>
            {
                Code = APIEnum.Fail,
                Message = $"查询开单申请列表失败：{ex.Message}",
                Data = new PagedResult<OrderApplicationDto>
                {
                    Items = new List<OrderApplicationDto>(),
                    TotalCount = 0,
                    PageIndex = request.PageIndex,
                    PageSize = request.PageSize,
                    TotalPages = 0
                }
            };
        }
    }

    /// <summary>
    /// 应用排序
    /// </summary>
    private IQueryable<OrderApplication> ApplySorting(IQueryable<OrderApplication> query, string? sortField, bool sortAscending)
    {
        return sortField?.ToLower() switch
        {
            "createtime" => sortAscending ? query.OrderBy(x => x.CreateTime) : query.OrderByDescending(x => x.CreateTime),
            "totalamount" => sortAscending ? query.OrderBy(x => x.TotalAmount) : query.OrderByDescending(x => x.TotalAmount),
            "status" => sortAscending ? query.OrderBy(x => x.Status) : query.OrderByDescending(x => x.Status),
            "applicationnumber" => sortAscending ? query.OrderBy(x => x.ApplicationNumber) : query.OrderByDescending(x => x.ApplicationNumber),
            _ => query.OrderByDescending(x => x.CreateTime) // 默认按创建时间降序
        };
    }

    /// <summary>
    /// 获取状态描述
    /// </summary>
    private string GetStatusDescription(OrderApplicationStatus status)
    {
        return status switch
        {
            OrderApplicationStatus.Draft => "草稿",
            OrderApplicationStatus.Pending => "待支付",
            OrderApplicationStatus.Paid => "已支付",
            OrderApplicationStatus.Progress => "进行中",
            OrderApplicationStatus.Completed => "已完成",
            OrderApplicationStatus.Cancelled => "已取消",
            _ => "未知状态"
        };
    }
}

/// <summary>
/// 获取开单申请详情处理器
/// </summary>
public class GetOrderApplicationDetailHandler : IRequestHandler<GetOrderApplicationDetailQuery, APIResult<OrderApplicationDetailDto>>
{
    private readonly IRepository<OrderApplication> _orderApplicationRepository;
    private readonly IRepository<OrderApplicationItem> _orderApplicationItemRepository;
    private readonly IMapper _mapper;
    private readonly ILogger<GetOrderApplicationDetailHandler> _logger;

    public GetOrderApplicationDetailHandler(
        IRepository<OrderApplication> orderApplicationRepository,
        IRepository<OrderApplicationItem> orderApplicationItemRepository,
        IMapper mapper,
        ILogger<GetOrderApplicationDetailHandler> logger)
    {
        _orderApplicationRepository = orderApplicationRepository;
        _orderApplicationItemRepository = orderApplicationItemRepository;
        _mapper = mapper;
        _logger = logger;
    }

    public async Task<APIResult<OrderApplicationDetailDto>> Handle(GetOrderApplicationDetailQuery request, CancellationToken cancellationToken)
    {
        try
        {
            _logger.LogInformation("开始查询开单申请详情，申请ID：{Id}，用户ID：{UserId}", request.Id, request.UserId);

            // 查询申请基本信息
            var orderApplication = await _orderApplicationRepository.GetQueryable()
                .Include(x => x.User)
                .Include(x => x.HospitalArea)
                .FirstOrDefaultAsync(x => x.Id == request.Id && !x.IsDeleted, cancellationToken);

            if (orderApplication == null)
            {
                _logger.LogWarning("开单申请不存在，申请ID：{Id}", request.Id);
                return new APIResult<OrderApplicationDetailDto>
                {
                    Code = APIEnum.Fail,
                    Message = "开单申请不存在",
                    Data = default(OrderApplicationDetailDto)!
                };
            }

            // 权限验证：如果指定了用户ID，则只能查询自己的申请
            if (request.UserId.HasValue && orderApplication.UserId != request.UserId.Value)
            {
                _logger.LogWarning("用户无权限查询该申请，申请ID：{Id}，用户ID：{UserId}，申请用户ID：{ApplicationUserId}", 
                    request.Id, request.UserId, orderApplication.UserId);
                return new APIResult<OrderApplicationDetailDto>
                {
                    Code = APIEnum.Fail,
                    Message = "无权限查询该申请",
                    Data = default(OrderApplicationDetailDto)!
                };
            }

            // 查询申请项目详情
            var orderApplicationItems = await _orderApplicationItemRepository.GetQueryable()
                .Include(x => x.MedicalProject)
                .Where(x => x.OrderApplicationId == request.Id && !x.IsDeleted)
                .ToListAsync(cancellationToken);

            // 构建详情DTO
            var detailDto = new OrderApplicationDetailDto
            {
                Id = orderApplication.Id,
                ApplicationNumber = orderApplication.ApplicationNumber,
                UserId = orderApplication.UserId,
                UserName = orderApplication.User?.RealName ?? orderApplication.User?.UserName ?? "未知用户",
                HospitalAreaId = orderApplication.HospitalAreaId,
                HospitalAreaName = orderApplication.HospitalArea?.Name ?? "未知院区",
                Status = orderApplication.Status,
                StatusDescription = GetStatusDescription(orderApplication.Status),
                ProjectCount = orderApplication.ProjectCount,
                TotalAmount = orderApplication.TotalAmount,
                Remarks = orderApplication.Remarks,
                AppointmentDate = orderApplication.AppointmentDate,
                AppointmentTimeSlot = orderApplication.AppointmentTimeSlot,
                ContactPhone = orderApplication.ContactPhone,
                CreateTime = orderApplication.CreateTime,
                UpdateTime = orderApplication.UpdateTime,
                Items = orderApplicationItems.Select(x => new OrderApplicationItemDetailDto
                {
                    Id = x.Id,
                    MedicalProjectId = x.MedicalProjectId,
                    ProjectName = x.ProjectName,
                    ProjectPrice = x.ProjectPrice,
                    ProjectDescription = x.ProjectDescription,
                    ProjectCategory = x.MedicalProject?.Category ?? ProjectCategory.Laboratory,
                    ProjectCode = x.MedicalProject?.Code,
                    Quantity = x.Quantity,
                    SubTotal = x.SubTotal,
                    EstimatedDuration = x.MedicalProject?.EstimatedDuration,
                    PreparationInstructions = x.MedicalProject?.PreparationInstructions
                }).ToList()
            };

            _logger.LogInformation("查询开单申请详情成功，申请ID：{Id}，项目数量：{ItemCount}", request.Id, detailDto.Items.Count);

            return new APIResult<OrderApplicationDetailDto>
            {
                Code = APIEnum.OK,
                Message = "查询成功",
                Data = detailDto
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "查询开单申请详情时发生异常，申请ID：{Id}", request.Id);
            
            return new APIResult<OrderApplicationDetailDto>
            {
                Code = APIEnum.Fail,
                Message = $"查询开单申请详情失败：{ex.Message}",
                Data = default(OrderApplicationDetailDto)!
            };
        }
    }

    /// <summary>
    /// 获取状态描述
    /// </summary>
    private string GetStatusDescription(OrderApplicationStatus status)
    {
        return status switch
        {
            OrderApplicationStatus.Draft => "草稿",
            OrderApplicationStatus.Pending => "待支付",
            OrderApplicationStatus.Paid => "已支付",
            OrderApplicationStatus.Progress => "进行中",
            OrderApplicationStatus.Completed => "已完成",
            OrderApplicationStatus.Cancelled => "已取消",
            _ => "未知状态"
        };
    }
}